package pac

import (
	"fmt"
	"strings"
	"time"

	db "slgw_web/application/gormdb"
	"slgw_web/serial/util"

	models "openzbox.com/frame/echo/models/sl_gw01"
)

var (
	initadress      string
	initadressError string
)

func init() {
	//初始化上报参数
	initadress = initAdress()
	initadressError = initAdressError()
	GetDeviceInfo_Detail()
}

// 定时上报数据
func TaskReportedData(sb models.DeviceInfo, types int) string {
	var collectData = initadress
	var collectDataError = initadressError
	// var deviceInfoID int64
	device_ID := sb.ID
	deviceInfoID := sb.DeviceInfoID
	var collectDataList = util.CollectDataList        //采集到的信息
	var deviceDetailList = util.DeviceInfo_DetailList //对应的上报点位
	if len(collectDataList) > 0 && len(deviceDetailList) > 0 {
		error := false
		for _, serialSlaveDetail := range collectDataList {
			for _, DeviceInfoDetailListData := range deviceDetailList {
				if sb.ID == DeviceInfoDetailListData.Device_ID {
					if serialSlaveDetail.ID == DeviceInfoDetailListData.Serial_Slave_Detail_ID { //如果采集到的是需要上报的点位
						if DeviceInfoDetailListData.MeterAddress == 1 {
							DeviceInfoDetailListData.MeterAddress = 2
						}
						value := serialSlaveDetail.Value //采集到的数据
						if value == "" {
							//数据采集错误的
							value = "0000"
						}
						valueError := serialSlaveDetail.ValueError //采集错误的标志
						if valueError == nil {
							valueError = new(string) // 初始化指针
							*valueError = "0000"
						}
						// if *valueError == "EEEE" {
						// 	error = true
						// }
						startIndex := (DeviceInfoDetailListData.MeterAddress - 2) * 4
						// endIndex := (DeviceInfoDetailListData.MeterAddress-2)*4 + 4
						endIndex := (DeviceInfoDetailListData.MeterAddress-2)*4 + int64(len(value))
						if serialSlaveDetail.Type == 0 || serialSlaveDetail.Type == 10 { //dlt645
							// endIndex = (DeviceInfoDetailListData.MeterAddress-2)*4 + int64(len(value))
							collectData = modifiedString(collectData, value, startIndex, endIndex)
							collectDataError = modifiedString(collectDataError, *valueError, startIndex, endIndex)
						} else {
							collectData = modifiedString(collectData, value, startIndex, endIndex)
							collectDataError = modifiedString(collectDataError, *valueError, startIndex, endIndex)
						}
						// fmt.Println("serialSlaveDetail.Type", serialSlaveDetail.Type)
						// fmt.Println("serialSlaveDetail.Value", serialSlaveDetail.Value)

						// deviceInfoID = sb.ID
					}
				}
			}
		}
		//fmt.Println("collectDataError", collectDataError)
		countOfZero := strings.Count(collectDataError, "E") //获取有几个0
		//默认可以上报
		if countOfZero == len(collectDataError) {
			// 字符串全是 "E" 不上报
			error = true

		}
		if error {
			util.Error("上报告警：数据采集失败不进行上报,name:" + sb.Name + ",设备id：" + sb.DeviceInfoID)
		}
		if types == 1 && !error { //定时上报
			//存入数据库
			// deviceInfoIDStr := fmt.Sprintf("%d", deviceInfoID)
			times := time.Now().Format("2006-01-02 15:04:05")
			// db := db.GetDB()
			// CollectDatas := models.CollectData{
			// 	Device_ID:  deviceInfoID,
			// 	Data:       collectData,
			// 	CreateTime: times,
			// }
			// db.Create(&CollectDatas)
			// sqlInssert := "INSERT INTO CollectData(DeviceInfoID,Data,CreateTime) VALUES(" + deviceInfoIDStr + ",'" + collectData + "','" + time + "')"
			// util.Insert(sqlInssert)
			//	sqlParm := "SELECT Data,CreateTime FROM CollectData order by  CreateTime desc limit " + "1"

			//如果开启断点重传功能，就把历史记录保存，并且每次发送前判断是否有需要续传的数据记录
			if util.IsRereported == 1 {
				db := db.GetDB()
				CollectDatas := models.CollectData{
					Device_ID:    device_ID,
					DeviceInfoID: deviceInfoID,
					Data:         collectData,
					CreateTime:   times,
				}
				db.Create(&CollectDatas)
				//fmt.Println("CollectDatas", CollectDatas)
				if len(util.RereportedTag) > 0 { //判断是否需要查询数据库续传
					RereportedDay := -1
					RI := 0
					//fmt.Println("util.RereportedTag1", util.RereportedTag)
					for RId, RItem := range util.RereportedTag {
						if RItem.DeviceInfo_ID == sb.ID {
							RereportedDay = RItem.RereportedDay
							RI = RId
							break
						}
					}
					//fmt.Println("RereportedDay1", RereportedDay)
					if RereportedDay != -1 {
						if RereportedDay != time.Now().Day() { //如果上次续传的日期是今天，就不再续传 等待下次
							//go func() {
							util.RereportedTag[RI].RereportedDay = time.Now().Day()
							time.Sleep(2 * time.Second) //延时 防止粘包
							var collectDataList []models.CollectData
							db.Where("DeviceInfoID = ? ", sb.DeviceInfoID).Find(&collectDataList)
							if len(collectDataList) > 0 {
								//把上传失败的重新上传
								for _, item := range collectDataList {
									ReportedData(item.Data, item.CreateTime, "09", sb)
									time.Sleep(1 * time.Second)
								}
							}
							//}()
							// //删除3天前的数据
							k := time.Now()
							d, _ := time.ParseDuration("-24h")
							s := k.Add(3 * d).Format("2006-01-02 00:00:00")
							result := db.Where("CreateTime<=?", s).Delete(&models.CollectData{})
							rows := result.RowsAffected //删除的条数
							if rows > 0 {
								db.Exec("VACUUM") //释放空闲的占用
							}
						}
					}
					//fmt.Println("util.RereportedTag2", util.RereportedTag)
				}

			}
			ReportedData(collectData, times, "09", sb)
		}
	}
	return collectData
}

// 整理采集 =》 上报 的地址数据
func modifiedString(s string, replacement string, startIndex int64, endIndex int64) string {
	bytes := []byte(s)

	if len(bytes) >= 8 {

		copy(bytes[startIndex:endIndex], []byte(replacement))
	}

	modifiedString := string(bytes)
	return modifiedString

}

// 实时上报
func ReportedData(str string, time string, firstStr string, sb models.DeviceInfo) {
	var data []models.CollectData
	var s = models.CollectData{
		Data:       str,
		CreateTime: time,
	}
	data = append(data, s)
	if len(data) > 0 {
		GroupAndProcessData(data, firstStr, sb)
	}
}

// 开始处理上报 历史数据
func ReportedDataSql(sqlParm string, firstStr string, sb models.DeviceInfo) {
	// db := util.GetDB()
	// rows, err := db.Query(sqlParm)
	// var data []models.CollectData
	// if err != nil {
	// 	util.Error("上报管理错误,获取需上报数据db错误:" + err.Error())
	// } else {
	// 	for rows.Next() {
	// 		var d models.CollectData
	// 		// 读取每一行的数据到变量中
	// 		err := rows.Scan(&d.Data, &d.CreateTime)
	// 		if err != nil {
	// 			util.Error("上报管理错误,获取需上报数据错误:" + err.Error())
	// 		}
	// 		data = append(data, d)
	// 	}
	// }

	var data []models.CollectData
	db := db.GetDB()
	db.Raw(sqlParm).Scan(&data)
	fmt.Println("data", data)
	if len(data) > 0 {
		GroupAndProcessData(data, firstStr, sb)
	}
}
func GroupAndProcessData(data []models.CollectData, firstStr string, sb models.DeviceInfo) {
	//拼接起来的数据长度不能超过2000，超过的分开发 (一次最多11条)
	for i := 0; i < len(data); i += 11 {
		end := i + 11
		if end > len(data) {
			end = len(data)
		}
		chunk := data[i:end]
		ProcessChunk(chunk, firstStr, sb)

	}
}

func ProcessChunk(data []models.CollectData, firstStr string, sb models.DeviceInfo) {
	input := ""
	userdata := ""
	lengthHex := "" //长度L
	for i, item := range data {
		if i <= 10 {
			times, _ := time.Parse("2006-01-02 15:04:05", item.CreateTime)
			tumeUnix := times.Unix()
			timeHex := ToHex(tumeUnix)
			userdata += timeHex + item.Data
		}
	}
	//firstStr := "09"
	serialNum := sb.DeviceInfoID
	length := int64((len(userdata) + 14) / 2)
	lengthHex = FourZero(ToHex(length))
	var hexStr = CalculateChecksum(firstStr + serialNum + userdata)
	input = "68" + lengthHex + "68" + firstStr + serialNum + userdata + hexStr + "16"
	// fmt.Println("input", input)
	SendData(input, sb)
}

// 获取上报点位数据
func GetDeviceInfo_Detail() {
	db := db.GetDB()
	var data []models.DeviceInfo_Detail
	db.Find(&data)
	util.DeviceInfo_DetailList = data
}
